#include <asm/system.h>
#include <asm/ldt.h>
#include <asm/desc.h>
+#include <asm/mmu_context.h>
#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
static void flush_ldt(void *null)
retval = copy_ldt(&mm->context, &old_mm->context);
up(&old_mm->context.sem);
}
+ if (retval == 0) {
+ spin_lock(&mm_unpinned_lock);
+ list_add(&mm->context.unpinned, &mm_unpinned);
+ spin_unlock(&mm_unpinned_lock);
+ }
return retval;
}
kfree(mm->context.ldt);
mm->context.size = 0;
}
+ spin_lock(&mm_unpinned_lock);
+ list_del(&mm->context.unpinned);
+ spin_unlock(&mm_unpinned_lock);
}
static int read_ldt(void __user * ptr, unsigned long bytecount)
}
#endif /* CONFIG_XEN_SHADOW_MODE */
+LIST_HEAD(mm_unpinned);
+DEFINE_SPINLOCK(mm_unpinned_lock);
+
static inline void mm_walk_set_prot(void *pt, pgprot_t flags)
{
struct page *page = virt_to_page(pt);
pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO), 0);
xen_pgd_pin(__pa(mm->pgd));
mm->context.pinned = 1;
+ spin_lock(&mm_unpinned_lock);
+ list_del(&mm->context.unpinned);
+ spin_unlock(&mm_unpinned_lock);
spin_unlock(&mm->page_table_lock);
}
pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0);
mm_walk(mm, PAGE_KERNEL);
mm->context.pinned = 0;
+ spin_lock(&mm_unpinned_lock);
+ list_add(&mm->context.unpinned, &mm_unpinned);
+ spin_unlock(&mm_unpinned_lock);
spin_unlock(&mm->page_table_lock);
}
+void mm_pin_all(void)
+{
+ while (!list_empty(&mm_unpinned))
+ mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
+ context.unpinned));
+}
+
void _arch_exit_mmap(struct mm_struct *mm)
{
struct task_struct *tsk = current;
struct semaphore sem;
void *ldt;
unsigned pinned:1;
+ struct list_head unpinned;
} mm_context_t;
+extern struct list_head mm_unpinned;
+extern spinlock_t mm_unpinned_lock;
+
/* mm/memory.c:exit_mmap hook */
extern void _arch_exit_mmap(struct mm_struct *mm);
#define arch_exit_mmap(_mm) _arch_exit_mmap(_mm)